sync w/ head.
/*
* If we are resuming after preemption, read how much work we have already
* done. This allows us to set the @done output parameter correctly.
+ * We also reset FOREIGNDOM here.
*/
- if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
+ if ( unlikely(count&(MMU_UPDATE_PREEMPTED|MMU_UPDATE_PREEMPT_FDOM_MASK)) )
{
+ if ( !(count & MMU_UPDATE_PREEMPTED) )
+ {
+ /* Count overflow into private FOREIGNDOM field. */
+ MEM_LOG("do_mmu_update count is too large");
+ rc = -EINVAL;
+ goto out;
+ }
count &= ~MMU_UPDATE_PREEMPTED;
+ domid = count >> MMU_UPDATE_PREEMPT_FDOM_SHIFT;
+ count &= ~MMU_UPDATE_PREEMPT_FDOM_MASK;
if ( unlikely(pdone != NULL) )
(void)get_user(done, pdone);
+ if ( (domid != current->id) &&
+ !do_extended_command(0, MMUEXT_SET_FOREIGNDOM | (domid << 16)) )
+ {
+ rc = -EINVAL;
+ goto out;
+ }
}
- if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) )
+ if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) ) {
- UNLOCK_BIGLOCK(d);
- return -EFAULT;
+ {
+ rc = -EFAULT;
+ goto out;
}
for ( i = 0; i < count; i++ )
*/
#define START_EXTENT_SHIFT 4 /* op[:4] == start_extent */
- #define PREEMPT_CHECK(_op) \
- if ( hypercall_preempt_check() ) { \
- hypercall_create_continuation( \
- __HYPERVISOR_dom_mem_op, 5, \
- (_op) | (i << START_EXTENT_SHIFT), \
- extent_list, nr_extents, extent_order, \
- (d == current->domain) ? DOMID_SELF : d->id); \
- return __HYPERVISOR_dom_mem_op; \
- }
+ #define PREEMPT_CHECK(_op) \
+ if ( hypercall_preempt_check() ) \
+ return hypercall_create_continuation( \
+ __HYPERVISOR_dom_mem_op, 5, \
+ (_op) | (i << START_EXTENT_SHIFT), \
+ extent_list, nr_extents, extent_order, \
- (d == current) ? DOMID_SELF : d->id)
++ (d == current->domain) ? DOMID_SELF : d->id);
static long
alloc_dom_mem(struct domain *d,